<?php

/**
 * @name OrderController
 * @desc 控制器(商品订单 order_pro 表)
 */
class OrderController extends UserCommonController
{
    //订单列表
    public function listAction(){
        $params = $this->post();

        $row = $params['pageSize'] ?? 12;
        $page = $params['page'] ?? 1;

        $cond = ['user_id'=> $this->user_info['user_id'], 'is_delete'=> 0];
        if(isset($params['status']) && $params['status'] != ''){
            $cond['status'] = $params['status'];
            if($params['status'] == 7){
                $cond['status#in'] = [7,8,9];
            }
        }

        $orderModel = OrderModel::getSingleton();
        $list = $orderModel->db
            ->field('order_id, order_no, buy_num_total, status, total_money, create_time')
            ->where($cond)
            ->order('order_id desc')
            ->limit(($page - 1) * $row, $row)
            ->select();

        $total = $orderModel->db
            ->where($cond)
            ->count();

        $orderProductSpecsModel = OrderProductSpecsModel::getSingleton();
        foreach($list as &$val){
            $val['product_list'] = $orderProductSpecsModel->findAll(['order_id'=> $val['order_id']], 'cover_img,spec_id');
            $val['status_text'] = OrderModel::$statusText[$val['status']];
        }

        $data = [
            'list' => $list,
            'total' => intval($total),
            'current'   => intval($page),
            'pageSize'  => intval($row),
            'page'  => intval($page),
            'pageNum'   => ceil($total/$row)
        ];

        $this->ajaxReturn(0, '', $data);
    }

    //详情
    public function detailAction(){
        $params = $this->post();

        if(!isset($params['order_no']) || !intval($params['order_no'])){
            $this->ajaxReturn(400, '必须传递订单编号');
        }

        $orderModel = OrderModel::getSingleton();
        $detail = $orderModel->find(['order_no'=> $params['order_no'], 'user_id'=> $this->user_info['user_id']],
            'status_three_time,order_id,order_no,shop_id,buy_num_total, status, total_money, total_money_pro,discount_money, pay_type, pay_money, pay_time, express_type, express_no, express_money, express_time, address_id,address_user_name,address_moble,address_text,create_time,is_delete'
        );
        if(!$detail){
            $this->ajaxReturn(400, '订单不存在');
        }
        if($detail['is_delete'] == 1){
            $this->ajaxReturn(400, '订单已删除');
        }

        $detail['count_down_time'] = 0;

        //过期配置时间
        $order_expire_time = SysConfigModel::getConfByIndex('order_expire_time');
        //订单超时验证
        if($detail['status'] == 0){
            if($detail['create_time'] <= time()-$order_expire_time) {
                //已过期
                $orderModel->update(['order_id'=> $detail['order_id']], ['status'=> 4]);
                $detail['status'] = 4;
            }else {
                //倒计时
                $detail['count_down_time'] = $order_expire_time - (time()-$detail['create_time']);
                $detail['count_down_time'] = $detail['count_down_time']>0? $detail['count_down_time']: 0;
            }
        }

        //订单商品
        $orderProductSpecsModel = OrderProductSpecsModel::getSingleton();
        $detail['product_list'] = $orderProductSpecsModel->findAll(['order_id'=> $detail['order_id']]);
        //店铺信息
        $detail['shop_address'] = '';
        $detail['shop_mobile'] = '';
        if($detail['shop_id']){
            $shopInfo = ShopModel::getSingleton()->find(['shop_id'=> $detail['shop_id']], 'address, mobile');
            $detail['shop_address'] = $shopInfo['address'];
            $detail['shop_mobile'] = $shopInfo['mobile'];
        }
        $detail['status_text'] = OrderModel::$statusText[$detail['status']];
        $detail['create_time_show'] = date('Y-m-d H:i:s', $detail['create_time']);

        //订单完成时间配置
        $order_back_day = SysConfigModel::getConfByIndex('order_back_day');
        //是否可以退款
        $can_back = 0;
        if(in_array($detail['status'], [1,2,3])){
            $can_back = 1;
            if($detail['status'] == 3 && $detail['status_three_time'] < (time()-86400*$order_back_day)){
                $can_back = 0;
            }
        }
        $detail['can_back'] = $can_back;
        $detail['back_money_text'] = OrderModel::$backMoneyText;

        $this->ajaxReturn(0, 'success', $detail);
    }

    //申请退款
    public function backmoneyAction(){
        $params = $this->post();
        if(!isset($params['order_no']) || !$params['order_no']){
            $this->ajaxReturn(400, '未获取到订单信息');
        }

        $orderModel = OrderModel::getSingleton();
        $orderInfo = $orderModel->find(['order_no'=> $params['order_no']]);
        if(!in_array($orderInfo['status'], [1,2,3])){
            $this->ajaxReturn(400, '操作失败');
        }
        //过期配置时间
        $order_back_day = SysConfigModel::getConfByIndex('order_back_day');
        if($orderInfo['status'] == 3 && $orderInfo['status_three_time'] < (time()-86400*$order_back_day)){
            $this->ajaxReturn(400, '订单已出退款期');
        }

        $userInfo = UserModel::getSingleton()->find(['user_id'=> $this->user_info['user_id']]);
        $curTime = time();

        try{
            \Vendor\DB::startTrans();

            //更该订单状态
            if(!$orderModel->update(['order_no'=> $params['order_no']], ['status'=> 7])){
                \Vendor\DB::rollback();
                $this->ajaxReturn('400', '操作失败', $orderModel->errMsg);
            }

            //写入订单记录
            $orderLogModel = OrderLogModel::getSingleton();
            if(!$orderLogModel->add([
                'order_id'  => $orderInfo['order_id'],
                'order_no'  => $orderInfo['order_no'],
                'user_id'   => $orderInfo['user_id'],
                'shop_id'   => $orderInfo['shop_id'],
                'status'    => 7,
                'description'   => '['.OrderModel::$statusText[7].']'.'用户：'.$userInfo['nick_name'].'，申请了退款.',
                'create_time'   => $curTime
            ])){
                \Vendor\DB::rollback();
                $this->ajaxReturn(400, '操作失败.', $orderLogModel->errMsg);
            }

            \Vendor\DB::commit();
        }catch(Exception $e){
            \Vendor\DB::rollback();
            $this->ajaxReturn(400, '下单失败，请返回重试', $e->getMessage());
        }

        $this->ajaxReturn(0, '申请成功');
    }

    //收银台
    public function cashierAction(){
        $params = $this->post();

        if(!isset($params['order_no']) || !intval($params['order_no'])){
            $this->ajaxReturn(400, '必须传递订单编号');
        }

        $orderModel = OrderModel::getSingleton();
        $detail = $orderModel->find(['order_no'=> $params['order_no'], 'user_id'=> $this->user_info['user_id']],
            'order_id,order_no,shop_id,buy_num_total, status, total_money, total_money_pro,discount_money, pay_type, pay_money, pay_time, express_type, express_no, express_money, express_time, address_id,address_user_name,address_moble,address_text,create_time,is_delete'
        );
        if(!$detail){
            $this->ajaxReturn(400, '订单不存在');
        }
        if($detail['is_delete'] == 1){
            $this->ajaxReturn(400, '订单已删除');
        }
        if($detail['status'] != 0){
            $this->ajaxReturn(400, '订单非待支付状态，请返回。');
        }
        //过期配置时间
        $order_expire_time = SysConfigModel::getConfByIndex('order_expire_time');
        if($detail['create_time'] <= time()-$order_expire_time) {
            //已过期
            $orderModel->update(['order_id'=> $detail['order_id']], ['status'=> 4]);
            $detail['status'] = 4;
            $this->ajaxReturn(400, '订单已过期');
        }

        //订单剩余支付时间
        $time_expire = $order_expire_time - (time()-$detail['create_time']);

        $tools = new \Vendor\WxPay\sdk\JsApiPay();
//        $openId = $tools->GetOpenid();
        $userInfo = UserModel::getSingleton()->find(['user_id'=> $this->user_info['user_id']]);
        $openId = $userInfo['open_id'];

        $total_fee = $detail['total_money'] * 100;
//        $total_fee = 1;

        //②、统一下单
        $input = new \Vendor\WxPay\lib\WxPayUnifiedOrder();
        $input->SetBody('[超v购]-'.$detail['order_no']);
        $input->SetAttach("超V购");
        $input->SetOut_trade_no($detail['order_no'].'_'.rand(10000,99999));
        $input->SetTotal_fee($total_fee);
        $input->SetTime_start(date("YmdHis"));
        $input->SetTime_expire(date("YmdHis", time() + $time_expire));
        $input->SetGoods_tag("超v购");
        $input->SetNotify_url("http://cvgshop.czxb.com/api/callback/index/");
        $input->SetTrade_type("JSAPI");
        $input->SetOpenid($openId);
        $order = \Vendor\WxPay\lib\WxPayApi::unifiedOrder($input);

//        echo '<font color="#f00"><b>统一下单支付单信息</b></font><br/>';
//        printf_info($order);
        $jsApiParameters = $tools->GetJsApiParameters($order);

        $this->ajaxReturn(0, 'success', $jsApiParameters);

//获取共享收货地址js函数参数
//        $editAddress = $tools->GetEditAddressParameters();
    }

    public function checkpayAction(){
        $order_no = $this->post('order_no');
        if(!$order_no){
            $this->ajaxReturn(400, 'fail');
        }

        $orderInfo = OrderModel::getSingleton()->find(['order_no'=> $order_no, 'status#in'=> [1,2,3,7,8,9]]);
        if(!$orderInfo){
            $this->ajaxReturn(0, '支付失败', 0);
        }
        $this->ajaxReturn(0, 'success', 1);
    }

    //过期设置
    public function expireAction(){
        $params = $this->post();
        if(!isset($params['order_no']) || !$params['order_no']){
            $this->ajaxReturn(400, '未获取订单号');
        }
        $orderModel = OrderModel::getSingleton();
        $orderInfo = $orderModel->find(['order_no'=> $params['order_no']]);

        if($orderInfo['status'] != 0){
            $this->ajaxReturn(400, '订单非待支付');
        }

        $order_expire_time = SysConfigModel::getConfByIndex('order_expire_time');
        if($orderInfo['create_time']> time()-$order_expire_time){
            $this->ajaxReturn(400, '订单未过期');
        }

        if(!$orderModel->update(['order_no'=> $params['order_no']], ['status'=> 4])){
            $this->ajaxReturn(400, 'fail');
        }
        $this->ajaxReturn(0, 'success');
    }

    //提交购物车(待结算页面)
    public function checkoutAction(){
        $params = $this->post();

        if(isset($params['page']) && $params['page'] == 'product_detail'){
            if(!isset($params['spec_id'])){
                $this->ajaxReturn(400, '必须选择商品');
            }
            $specData = [
                'spec_id'   => $params['spec_id'],
                'buy_num'   => 1
            ];
        }else {
            //获取购物车已选商品
            $specData = [];
        }

        $productData = $this->checktotal( $specData );

        $shopInfo = ShopModel::getSingleton()->find(['shop_id'=> $this->user_info['offline_shop_id']], 'address,tags,mobile,express_money');
        $returnData = [
            'total_num'=> $productData['total_num'],
            'total_money'=> $productData['total_money'],
            'product_list'=> $productData['list'],
            'shop_info' => $shopInfo
        ];

        $this->ajaxReturn(0, 'success', $returnData);
    }

    //计算购物车已勾选商品结算信息
    public function checktotal( $specData=[] ){
        if(empty($specData)){
            //查询购物车勾选信息
            $cond = ['c.user_id'=> $this->user_info['user_id'], 'c.checked'=> 1, 'sps.is_show'=> 1,'sps.shop_id'=> $this->user_info['offline_shop_id']];
            $cartModel = CartModel::getSingleton();
            $list = $cartModel->db
                ->field('c.buy_num, c.checked, c.spec_id,p.product_id,p.product_name, p.cover_img,ps.spec_id,ps.point,ps.spec_name_full, ps.unit_money, sps.shop_spec_stock,sps.shop_spec_stock_total,sps.is_show,sps.id,sps.shop_id')
                ->alias('c')
                ->join(['product', 'p'], ['c.product_id'=> 'p.product_id'], 'inner join')
                ->join(['product_specs', 'ps'], ['c.spec_id'=> 'ps.spec_id'], 'inner join')
                ->join(['shop_product_specs', 'sps'], ['c.spec_id'=> 'sps.spec_id'], 'inner join')
                ->where_c($cond)
                ->select();
        }else {
            //从商品详情页直接购买的
            $cond = ['sps.is_show'=> 1, 'sps.shop_id'=> $this->user_info['offline_shop_id'], 'sps.spec_id'=> $specData['spec_id']];
            $list = ShopProductSpecsModel::getSingleton()->db
                ->alias('sps')
                ->field('p.product_id,p.product_name, p.cover_img,ps.point,ps.spec_id,ps.spec_name_full, ps.unit_money, sps.shop_spec_stock,sps.shop_spec_stock_total,sps.is_show,sps.spec_id,sps.id,sps.shop_id')
                ->join(['product', 'p'], ['sps.product_id'=> 'p.product_id'], 'inner join')
                ->join(['product_specs', 'ps'], ['sps.spec_id'=> 'ps.spec_id'], 'inner join')
                ->where_c($cond)
                ->select();
            $list[0]['buy_num'] = $specData['buy_num'];
        }
        if(!$list || empty($list)){
            $this->ajaxReturn(400, '必须先择商品');
        }

        $total_num = 0;
        $total_money = 0;
        $kpi_point = 0;
        foreach ($list as &$val){
            if($val['is_show'] == 0){
                $this->ajaxReturn(400, $val['product_name'].'已下架，无法购买');
            }
            if($val['shop_spec_stock'] < $val['buy_num']){
                $this->ajaxReturn(400, '来晚了，库存已不足，请返回重新下单');
            }
            if($val['shop_id'] != $this->user_info['offline_shop_id']){
                $this->ajaxReturn(400, '非店铺商品，请联系店铺购买');
            }
            $val['product_name_full'] = $val['product_name']. ' '. $val['spec_name_full'];
            $val['p_total_money'] = $val['unit_money'] * $val['buy_num'];
            $total_num += $val['buy_num'];
            $total_money += $val['p_total_money'];
            $kpi_point += $val['point'];
        }

        $data = [
            'list'  => $list,
            'total_num' => $total_num,
            'total_money'   => $total_money,
            'kpi_point' => $kpi_point
        ];
        return $data;
    }

    //下单
    public function addAction(){
        $params = $this->post();
        $rule = [
            'address_id'    => 'require',
            'checkout_type'      => 'require',
            'express_type'  => 'require',
        ];
        $msg = [
            'address_id.require'    => '必须选择收获地址',
            'checkout_type.require'   => '必须选择支付方式',
            'express_type.require'  => '必须先择配送方式'
        ];
        $validate = new \Vendor\Kvalidate($rule,$msg);
        if(!$validate->check($params)){
            $this->ajaxReturn(400, $validate->getError());
        }
        //判断下单频率
        $lastOrder = OrderModel::getSingleton()->db
            ->field('create_time')
            ->where(['user_id'=> $this->user_info['user_id'], 'create_time#>'=> time()-3])
            ->order('order_id desc')
            ->find();
        if($lastOrder){
            $this->ajaxReturn(400, '操作太快了，请勿重复下单');
        }
        $addressDeatail = UserAddressModel::getSingleton()->find([
            'user_id'=> $this->user_info['user_id'],
            'id'=> $params['address_id']
        ]);
        if(!$addressDeatail){
            $this->ajaxReturn(400, '收货地址不存在');
        }

        if(isset($params['page']) && $params['page'] == 'product_detail'){
            if(!isset($params['spec_id'])){
                $this->ajaxReturn(400, '必须选择商品');
            }
            $specData = [
                'spec_id'   => $params['spec_id'],
                'buy_num'   => 1
            ];
        }else {
            $specData = [];
        }
        //购买商品列表
        $productSpecData = $this->checktotal( $specData );
        //购买商品用户信息
        $userDetail = UserModel::getSingleton()->find(['user_id'=> $this->user_info['user_id']], 'nick_name, user_id');
        //出生商品店铺信息
        $sellShopDetail = ShopModel::getSingleton()->find(['shop_id'=> $this->user_info['offline_shop_id']], 'shop_id,express_money');
        //需要支付的金额
        $total_money = $productSpecData['total_money'];
        //物流费用
        $express_money = 0;
        if($params['express_type'] == 1){
            $express_money = $sellShopDetail['express_money'];
            $total_money += $express_money;
        }
        $order_no = \Vendor\Kstring::orderNo20();   //订单号
        $curTime = time();
        try{
            \Vendor\DB::startTrans();

            //写入订单表
            $orderModel = OrderModel::getSingleton();
            $order_id = $orderModel->add([
                'order_no'          => $order_no,
                'user_id'           => $this->user_info['user_id'],
                'shop_id'           => $sellShopDetail['shop_id'],
                'buy_num_total'     => $productSpecData['total_num'],
                'status'            => 0,
                'total_money'       => $total_money,
                'total_money_pro'   => $productSpecData['total_money'],
                'kpi_point'         => $productSpecData['kpi_point'],
                'discount_money'    => 0,
                'discount_point'    => 0,
                'express_type'      => $params['express_type'],
                'express_money'     => $express_money,
                'address_id'        => $addressDeatail['id'],
                'address_user_name' => $addressDeatail['user_name'],
                'address_moble'     => $addressDeatail['moble'],
                'address_text'      => $addressDeatail['areas'].' '.$addressDeatail['address'],
                'create_time'       => $curTime
            ]);
            if(!$order_id){
                $this->ajaxReturn(400, '下单失败，请重试。', $orderModel->errMsg);
            }

            //写入订单商品关联表
            $orderProductSpecsModel = OrderProductSpecsModel::getSingleton();
            foreach($productSpecData['list'] as $val){
                if(!$orderProductSpecsModel->add([
                    'order_id'      => $order_id,
                    'shop_id'       => $val['shop_id'],
                    'product_id'    => $val['product_id'],
                    'spec_id'       => $val['spec_id'],
                    'buy_num'       => $val['buy_num'],
                    'product_name'  => $val['product_name'],
                    'spec_name_full'    => $val['spec_name_full'],
                    'unit_money'    => $val['unit_money'],
                    'p_total_money'     => $val['p_total_money'],
                    'cover_img'     => $val['cover_img'],
                    'create_time'     => $curTime
                ])){
                    \Vendor\DB::rollback();
                    $this->ajaxReturn(400, '下单失败，请重试..', $orderProductSpecsModel->errMsg);
                }
                if(isset($params['cloud'])){
                    //云端商品
                }else {
                    $shopProductSpecsModel = ShopProductSpecsModel::getSingleton();
                    //减库存
                    if(!$shopProductSpecsModel->update(['id'=> $val['id']], ['shop_spec_stock'=> $val['shop_spec_stock']-$val['buy_num'],'update_time'=> $curTime])){
                        \Vendor\DB::rollback();
                        $this->ajaxReturn(400, '下单失败,请重试...', $shopProductSpecsModel->errMsg);
                    }
                    //更新该商品所有规格总库存(改到定时任务做)
//                    if(!$shopProductSpecsModel->update(['shop_id'=> $val['shop_id'], 'product_id'=> $val['product_id']], [
//                        'shop_spec_stock_total' => $val['shop_spec_stock_total']-$val['buy_num'],
//                        'update_time'   => $curTime
//                    ])){
//                        \Vendor\DB::rollback();
//                        $this->ajaxReturn(400, '下单失败！请重试...', $shopProductSpecsModel->errMsg);
//                    }
                }
                //清除购物车
                $cartModel = CartModel::getSingleton();
                $cond = ['user_id'=> $this->user_info['user_id'], 'spec_id'=> $val['spec_id']];
                $exist = $cartModel->find($cond);
                if($exist && !$cartModel->delete($cond)){
                    \Vendor\DB::rollback();
                    $this->ajaxReturn(400, '下单失败,请重试!', $cartModel->errMsg);
                }
            }

            //订单记录
            $orderLogModel = OrderLogModel::getSingleton();
            if(!$orderLogModel->add([
                'order_id'  => $order_id,
                'order_no'  => $order_no,
                'user_id'   => $this->user_info['user_id'],
                'shop_id'   => $this->user_info['offline_shop_id'],
                'status'    => 0,
                'description'   => '['.OrderModel::$statusText[0].']'.'用户：'.$userDetail['nick_name'].'，下单成功（等待支付）',
                'create_time'   => $curTime
            ])){
                \Vendor\DB::rollback();
                $this->ajaxReturn(400, '下单失败！请重试...', $orderLogModel->errMsg);
            }

            \Vendor\DB::commit();
        }catch(Exception $e){
            \Vendor\DB::rollback();
            $this->ajaxReturn(400, '下单失败，请返回重试', $e->getMessage());
        }

        $this->ajaxReturn(0, 'success', $order_no);
    }

    //微信支付回调
    public function cbwxAction(){
        $params = $this->post();

        //todo:接口鉴权

        $order_id = intval($params['order_id']);
        $pay_money = $params['money'];

        $is_success = 0;
        if($order_id && $pay_money){
            $orderProModel = OrderProModel::getSingleton();
            if($orderProModel->update(['order_id'=> $order_id], ['status'=> 1, 'pay_money'=> $pay_money])){
                $is_success = 1;
                echo 'success';
            }
        }

        //记录回调
        $payCallbackModel = PayCallbackModel::getSingleton();
        $payCallbackModel->add([
            'type'  => 1,
            'order_id'  => $order_id,
            'params_str'    => json_encode($params),
            'is_success'    => $is_success
        ]);
    }

}
